using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class BlockController : MonoBehaviour
{
    public bool Moving;
    public bool PickedUp;
    public bool LocalPickedUp;
    public List<Transform> Cubes;

    private float speed = 10;
    private Vector3 direction;
    public bool colliding, lockX, lockZ;

    // Use this for initialization
    void Start()
    {
        PickedUp = false;
        Moving = false;
        colliding = false;
        for (int i = 0; i < 4; i++)
        {
            Cubes.Add(transform.FindChild("cube" + i));
        }
    }

    // Update is called once per frame
    void Update()
    {
        if ((PickedUp || Moving) && DataManager.Instance.isRunning && DataManager.Instance.networkingActivated)
        {
            networkView.RPC("updatePositionAndRotation", RPCMode.OthersBuffered, transform.position, transform.rotation, PickedUp, Moving);
        }
        if (Moving)
        {
            Vector3 newPosition = transform.position + speed * direction * Time.smoothDeltaTime;
            if (lockX)
                newPosition.x = transform.position.x;
            if (lockZ)
                newPosition.z = transform.position.z;

            if (newPosition == transform.position)
            {
                Grid.SetBlock(this);
            }
            else
            {
                transform.position = newPosition;
            }

            #region Old code
            //List<float> possibleCollisions = new List<float>();
            //Vector3 oldPos = transform.position;
            //Vector3 newPos = oldPos + speed * direction * Time.smoothDeltaTime;

            //if ((int)newPos.x != (int)oldPos.x)
            //{
            //    int x = newPos.x > oldPos.x ? (int)newPos.x : (int)oldPos.x;
            //    possibleCollisions.Add((x - oldPos.x) / (newPos.x - oldPos.x));
            //}

            //if ((int)newPos.z != (int)oldPos.z)
            //{
            //    int z = newPos.z > oldPos.z ? (int)newPos.z : (int)oldPos.z;
            //    possibleCollisions.Add((z - oldPos.z) / (newPos.z - oldPos.z));
            //}

            //if (possibleCollisions.Count == 0)
            //    transform.position = newPos;
            //else
            //{
            //    foreach (float t in possibleCollisions.OrderBy(t => t))
            //    {

            //    }
            //}

            /*
            if (doneRoundingZ)
                return;

            pos += direction * speed * Time.deltaTime;

            if (pos.x > XCap)
            {
                pos.x = XCap;
                doneRoundingX = true;
            }
            if (pos.x < -XCap)
            {
                pos.x = -XCap;
                doneRoundingX = true;
            }

            if (pos.z > ZCap)
            {
                pos.z = ZCap;
                doneRoundingZ = true;
                Moving = false;
            }
            if (pos.z < -ZCap)
            {
                pos.z = -ZCap;
                doneRoundingZ = true;
                Moving = false;
            }

            if (pos.x > XCap)
            {
                pos.x = XCap;
                doneRoundingX = true;
            }
            if (pos.x < -XCap)
            {
                pos.x = -XCap;
                doneRoundingX = true;
            }

            if (pos.z > ZCap)
            {
                pos.z = ZCap;
                doneRoundingZ = true;
                Moving = false;
            }
            if (pos.z < -ZCap)
            {
                pos.z = -ZCap;
                doneRoundingZ = true;
                Moving = false;
            }

            newPos.y = 0;
            if (!doneRoundingX) newPos.x = Mathf.Round(pos.x);
            if (!doneRoundingZ) newPos.z = Mathf.Round(pos.z);

            transform.position = newPos;

            if (!doneRoundingX) newPos.x = Mathf.Round(pos.x);
            if (!doneRoundingZ) newPos.z = Mathf.Round(pos.z);

            transform.position = newPos;
             */
            #endregion
        }
        else
        {
            transform.position = Vector3.Lerp(transform.position, new Vector3(transform.position.x, -1, transform.position.z), 5 * Time.smoothDeltaTime);
        }
    }

    void OnTriggerEnter(Collider other)
    {
        print("collision");
        if (other.gameObject.tag == "block")
        {
            BlockController otherBlock;
            if (other.gameObject.transform.parent)
                otherBlock = other.gameObject.transform.parent.GetComponent<BlockController>();
            else
                otherBlock = other.gameObject.GetComponent<BlockController>();

            if (otherBlock.Moving)
                otherBlock.colliding = true;
        }
    }

    void OnCollisionEnter(Collision other)
    {
        print("collision");
        if (other.gameObject.tag == "block")
            print("with a block");
    }

    void OnTriggerExit(Collider other)
    {
        if (other.gameObject.tag == "block")
        {
            colliding = false;
        }
    }

    public bool Shoot(Vector3 direction, float speed)
    {
        this.speed = speed;
        return Shoot(direction);
    }

    public bool Shoot(Vector3 direction)
    {
        if (colliding)
            return false;

        direction.y = 0;
        direction = direction.normalized;
        this.direction = direction;

        Moving = true;
        PickedUp = false;
        lockX = false;
        lockZ = false;

        return true;
    }

    [RPC]
    public void updatePositionAndRotation(Vector3 pos, Quaternion rot, bool pu, bool mv)
    {
        transform.position = pos;
        transform.rotation = rot;
        PickedUp = pu;
        Moving = mv;
    }
}
